package com.zj.core.services

import android.annotation.SuppressLint
import android.app.Service
import android.content.Intent
import android.os.*
import org.greenrobot.eventbus.EventBus
import com.bletoothutils.BleToothKitUtil
import com.clj.fastble.BleManager
import com.bletoothutils.BleToothKitUtil.*
import com.zj.core.bean.EventBusMessage.Companion.BLUE_TOOTH_IS_CONNECT_FAILE
import com.zj.core.bean.EventBusMessage.Companion.BLUE_TOOTH_IS_CONNECT_OK
import com.zj.core.bean.EventBusMessage.Companion.BLUE_TOOTH_IS_FAILE
import com.zj.core.bean.EventBusMessage.Companion.BLUE_TOOTH_IS_OPEN
import com.zj.core.bean.EventBusMessage.Companion.BLUE_TOOTH_IS_SEACH_CANCEL
import com.zj.core.bean.EventBusMessage.Companion.BLUE_TOOTH_IS_SEACH_IN
import com.zj.core.bean.EventBusMessage.Companion.BLUE_TOOTH_IS_SEACH_STOP
import com.zj.core.bean.EventBusMessage.Companion.BLUE_TOOTH_STATUS_TAG
import com.zj.core.base.BaseApplication
import com.fileutils.SoundPoolUtils
import com.zj.core.bean.EventBusMessage.Companion.BLUE_TOOTH_DATA_TAG
import com.zj.core.tools.Constant
import com.fileutils.ByteUtils
import com.fileutils.SPUtils
import com.dialogutils.ToastUtil
import com.fileutils.StringUtils
import com.zj.datacoll.BleToothManager
import com.zj.core.bean.EventBusMessage
import com.zj.core.tools.Constant.Companion.DERIVE_UUID_VALUE



@SuppressLint("Registered")
class BleToothService: Service(){
    private var mSendBool = true
    private var mSpoBuf = ""
    private var mBmpBuf = ""

    companion object {
        var mConnectStatus = false         //设备连接状态
        var mDisConnectStatus = false      //设备断开状态
        var mConnectMac: String? =""                     //当前连接设备mac地址
        @SuppressLint("StaticFieldLeak")
        var mBleUtils: BleToothKitUtil? = null
    }

    /**
     * 蓝牙初始化配置
     */
    override fun onCreate() {
        super.onCreate()
        mBleUtils = BleToothKitUtil(BaseApplication.context)
        mBleUtils?.setHandler(CustomHandler())     //注册handler

        BleManager.getInstance()
            .enableLog(true)
            .setReConnectCount(1, 5000)
            .setConnectOverTime(20000).operateTimeout = 5000
    }

    override fun onBind(intent: Intent?): IBinder? {
        return BleToothBind()
    }

    private class BleToothBind:BleToothManager.Stub(){
        override fun connectBle(mac: String?){
            mDisConnectStatus = false
            if (DERIVE_UUID_VALUE[mac?.substring(1,3)]!= null){     //是否支持该设备连接
                mBleUtils?.searchDevice(mac)
            } else {
                ToastUtil.showShort(BaseApplication.context, "抱歉，该设备暂不允许接入")
            }
        }

        override fun disConnectBle(mac: String?) {
            mBleUtils?.disconnectBleDevice(mac)
        }
    }

    /**
     * 蓝牙状态
     */
    @SuppressLint("HandlerLeak")
    private inner class CustomHandler:Handler(){
        override fun handleMessage(msg: Message){
            super.handleMessage(msg)

            val mes = EventBusMessage()
            mes.keycode = BLUE_TOOTH_STATUS_TAG
            when (msg.what) {
                BLUE_TOOTH_OPEN_CLOSE ->{                 //蓝牙打开状态
                    if (msg.obj as Boolean) {
                        mes.notify = BLUE_TOOTH_IS_OPEN
                        EventBus.getDefault().post(mes)
                    } else {
                        mes.notify = BLUE_TOOTH_IS_FAILE
                        EventBus.getDefault().post(mes)
                    }
                }

                BLUE_TOOTH_SEACH_START -> {                 //开始搜索设备
                    mes.notify = BLUE_TOOTH_IS_SEACH_IN
                    EventBus.getDefault().post(mes)
                }

                BLUE_TOOTH_SEACH_RESULT -> {                //搜索完成
                    mConnectStatus = true
                    mBleUtils?.connectDevice(msg.obj as String)
                }

                BLUE_TOOTH_SEACH_STOP -> {                  //停止搜索
                    mes.notify = BLUE_TOOTH_IS_SEACH_STOP
                    if (!mConnectStatus && !mDisConnectStatus) {
                        playVoice("voice_4.mp3",2)
                    }
                    EventBus.getDefault().post(mes)
                }

                BLUE_TOOTH_SEACH_CANCEL -> {
                    mes.notify = BLUE_TOOTH_IS_SEACH_CANCEL
                    EventBus.getDefault().post(mes)
                }

                BLUE_CONNECT_SUCCESS-> {                    //设备连接成功
                    mes.notify = BLUE_TOOTH_IS_CONNECT_OK
                    playVoice("voice_1.mp3",0)
                    mConnectMac = msg.obj.toString()
                    mBleUtils?.registerConnectListener(StringUtils.formatMac(
                        mConnectMac, ":"))
                    choiseConnectMeth(mConnectMac!!)
                    mes.mes = "断开"
                    EventBus.getDefault().post(mes)
                }

                BLUE_CONNECT_FAILE -> {
                    mes.notify = BLUE_TOOTH_IS_CONNECT_FAILE
                    playVoice("voice_4.mp3",2)                  //设备连接失败
                    mConnectMac = ""
                    mConnectStatus = false
                    EventBus.getDefault().post(mes)
                }

                BLUE_REGIST_CONNECT_FAILE -> {                //设备已断开
                    playVoice("voice_2.mp3",1)
                    mConnectMac = ""
                    mConnectStatus = false
                    mDisConnectStatus = true
                    mSendBool = true
                    mes.mes = "连接"
                    EventBus.getDefault().post(mes)
                }

                BLUE_DATA_CONNECT_FAILE-> { }                  //服务连接失败
                BLUE_DATA_CONNECT_SUCCESS -> { }               //服务连接成功

                BLUE_DATA_CONNECT_SEND -> {
                    val mBundle = msg.obj as Bundle
                    val mType = mBundle.getString("type")
                    val mByteArr = mBundle.getByteArray("byteArr")
                    checkDeviceType(mByteArr, mType)
                }
                else -> { }
            }
        }
    }

    /**
     * 对应类型数据解析
     *
     * @param data
     * @param deviceType
     */
    private fun checkDeviceType(data: ByteArray, deviceType: String){
        val mEventBean = EventBusMessage()
        mEventBean.keycode=BLUE_TOOTH_DATA_TAG

        when(deviceType){
            "0"->{                             //来家胎心仪
                val s = ByteUtils.bytesToHexString(data)
                val high = s.substring(0, 2)
                val low = s.substring(2, 4)
                val value = s.substring(4, 6)
                if (high == "ff" && low == "fc") {
                    val d = Integer.valueOf(value, 16)
                    mEventBean.mes="胎心$d"
                    EventBus.getDefault().post(mEventBean)
                }
            }

            "1"->{                             //鱼跃血氧仪
                val mDeviceBlood = ("血压" + Integer.valueOf(ByteUtils.toHexString1(data[1]), 16) + "/"
                        + Integer.valueOf(ByteUtils.toHexString1(data[3]), 16)
                        + "，脉搏" + Integer.valueOf(ByteUtils.toHexString1(data[14]), 16))
                mEventBean.mes=mDeviceBlood
                EventBus.getDefault().post(mEventBean)
            }

            "2"->{                             //额温枪
                val deviceValue = data[1].toInt() shl 8 or data[2].toInt()
                mEventBean.mes="体温" + deviceValue.toFloat() / 10
                EventBus.getDefault().post(mEventBean)
            }

            "3"->{                             //宝莱特血氧仪
                val mBottomFourth = ByteUtils.toHexString1(data[data.size - 4])          //每组数据倒数第四个值
                val mAntepenultimate = ByteUtils.toHexString1(data[data.size - 3])       //每组数据倒数第三个值
                val mPriorNumStr = ByteUtils.toHexString1(data[data.size - 2])           //每组数据倒数第二个值
                val mFinallyNumStr = ByteUtils.toHexString1(data[data.size - 1])        //每组数据倒数第一个值

                if (mPriorNumStr == "ff" && mFinallyNumStr == "00") {
                    if (mAntepenultimate == "ff" && mBottomFourth == "7f") {
                        if (!mSpoBuf.equals("") && !mBmpBuf.equals("")) {
                            if (mSendBool) {
                                val mOxygen = ("血氧" + Integer.valueOf(mSpoBuf, 16)
                                        + "，脉搏" + Integer.valueOf(mBmpBuf, 16))
                                mEventBean.mes=mOxygen
                                EventBus.getDefault().post(mEventBean)
                                mSendBool = false
                                mSpoBuf = ""
                                mBmpBuf = ""
                            }
                        }
                    } else {
                        mSpoBuf = mBottomFourth
                        mBmpBuf = mAntepenultimate
                    }
                }
            }

            "4"->{                            //香山婴儿秤
                val mHeadData = ByteUtils.toHexString1(data[0])
                val mOrderCode = ByteUtils.toHexString1(data[1])
                val mLockStatu = ByteUtils.toHexString1(data[10])
                if (mHeadData == "ff" && mOrderCode == "a5" && mLockStatu == "aa") {   //数据已锁定
                    val weight = (data[2].toInt() shl 8) + data[3]
                    val height = (data[6].toInt() shl 8) + data[7]
                    if (mSendBool) {
                        val mStature = "身高" + height / 10 + "，体重" + weight / 1000
                        mEventBean.mes=mStature
                        EventBus.getDefault().post(mEventBean)
                        mSendBool = false
                    }
                }
            }

            "6"->{                             //鱼跃血糖仪
                mEventBean.mes="血糖" + Integer.valueOf(ByteUtils.toHexString1(data[10]), 16).toFloat()/10
                EventBus.getDefault().post(mEventBean)
            }

            "7"->{                             //耳温枪
                if (data.size === 20 && ByteUtils.toHexString1(data[0]) == "ff"
                    && ByteUtils.toHexString1(data[1]) == "fe"
                    && ByteUtils.toHexString1(data[2]) == "06"
                    && ByteUtils.toHexString1(data[4]) == "22"
                    && ByteUtils.toHexString1(data[5]) == "65"
                ) {
                    val mByte = ByteArray(2)
                    mByte[0] = data[7]
                    mByte[1] = data[6]
                    mEventBean.mes="体温" + Integer.valueOf(ByteUtils.toHexString1(mByte), 16).toFloat()/10
                    EventBus.getDefault().post(mEventBean)
                }
            }
        }
    }

    /**
     * 选择设备对应的数据模式
     *
     * @param mac
     */
    private fun choiseConnectMeth(mac: String){
        val connectMes = Constant.DERIVE_UUID_VALUE[mac.substring(1,3)]?.split(":")
        val serviceUUID = java.util.UUID.fromString(connectMes?.get(0))
        val notifyUUID = java.util.UUID.fromString(connectMes?.get(1))

        if (connectMes?.get(3)== "1"){                 //目前鱼跃血压仪使用indicate方式通信
            mBleUtils?.indicateBleTooth(StringUtils.formatMac(mac, ":"), serviceUUID, notifyUUID, connectMes[3])
        } else {
            mBleUtils?.notifyBleTooth(StringUtils.formatMac(mac, ":"), serviceUUID, notifyUUID, connectMes?.get(3))
        }
    }

    /**
     * 震动
     */
    private fun playVibrator() {
        SoundPoolUtils.getInstance(BaseApplication.context).startVibrator(200)
    }

    /**
     * 播放声音
     *
     * @param res voice_1.mp3     设备连接成功
     * voice_2.mp3     设备连接失败
     */
    private fun playVoice(res: String) {
        SoundPoolUtils.playMedia(BaseApplication.context, res).start()
    }

    /**
     * 播放声音
     */
    private fun playVoice(res: String,voice:Int){
        if(SPUtils.getVoiceStatus(BaseApplication.context, Constant.NOTIFY_VOICE_KEY)){
            playVoice(res)
        }else{
            when (voice) {
                0 -> ToastUtil.showShort(BaseApplication.context,"设备已连接")
                1 -> ToastUtil.showShort(BaseApplication.context,"设备已断开")
                else -> ToastUtil.showShort(BaseApplication.context,"设备连接失败")
            }
        }
    }

    fun destroyBle() {
        if (!mConnectMac.equals("")) {
            mBleUtils?.disconnectBleDevice(mConnectMac)
        }
    }
}